package main

import (
	"fmt"
)

func swap(a int, b int) {
	fmt.Println("调用传值交换方法")
	var temp int
	temp = a
	a = b
	b = temp
}

func swapAddr(pa *int, pb *int) {
	fmt.Println("调用传址交换方法1")
	// 交换指针所指地址存储的值，意思就是互换了内存地址所对应的值
	var temp int
	temp = *pa
	*pa = *pb
	*pb = temp
}

func swapAddr2(pa *int, pb *int) {
	fmt.Println("调用传址交换方法2")
	// 交换指针所指地址，但是地址里存储的值没有变，意思就是互换了内存地址，没改地址对应的值
	var temp *int
	temp = pa
	pa = pb
	pb = temp
}
func main() {
	var a int = 10
	var b = 20

	fmt.Println("交换前，a = ", a, " b = ", b)
	swap(a, b)
	fmt.Println("a = ", a, " b = ", b)
	swapAddr(&a, &b)
	fmt.Println("a = ", a, " b = ", b)
	swapAddr2(&a, &b)
	fmt.Println("a = ", a, " b = ", b)

	// 指针类型是用于表示指针的类型。写法为在类型名前加*。指针类型可基于任意类型
	var p *int
	// &是地址运算符。放在值类型的前面用于返回所存储值的内存地址
	p = &a
	fmt.Println("a的地址是	:", &a)
	fmt.Println("p的值为		:", p)
	// *为间接运算符。放在指针类型的变量前可返回其所指向的值。这称为解引用
	fmt.Println("p所指地址对应的变量值为		:", *p)

	// 内置函数new可创建指针变量。它返回指定类型零值实例的指针
	var x = new(int)
	x = &a
	fmt.Println("内置函数创建指针变量x，指地址对应的变量值为		:", *x)

	// 二级指针
	var pp **int
	pp = &p
	fmt.Println("p的地址		:", &p)
	fmt.Println("pp的值为	:", pp)
	fmt.Println("pp的所指地址	:", *pp)
	fmt.Println("pp的所指地址的值	:", **pp)
}
